package wx

import (
	"backend/pkg/logging"
	"backend/pkg/request"
	"backend/pkg/setting"
	"bytes"
	"fmt"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/json"
)

const REDIS_KEY_ACCESS_TOKEN string = "wxaToken"

var Code string
var CookieKey string
var AppId string
var Secret string

func init() {
	AppId = setting.Appid
	Secret = setting.Secret
}

/**
	获取微信sessionkey
 */
func GetSessionKey(c *gin.Context) (map[string]interface{}, bool) {
	session := sessions.Default(c)

	var res string
	// session 获取到直接返回
	sk := session.Get(CookieKey)
	if sk != nil {
		res = sk.(string)
	} else {
		// 微信获取
		baseUrl := "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=%s"
		res = request.Get(fmt.Sprintf(baseUrl, AppId, Secret, Code, "authorization_code"))
	}

	var resMap map[string]interface{}
	decoder := json.NewDecoder(bytes.NewBufferString(res))
	decoder.Decode(&resMap)
	if _, ok := resMap["session_key"]; ok && sk == nil {
		session.Set(CookieKey, res)
		session.Options(sessions.Options{
			MaxAge: 3600,
		})
		session.Save()
		/*// 更新session_key
		models.WxEditUser(models.WxUser{
			Openid:     resMap["openid"].(string),
			SessionKey: resMap["session_key"].(string),
		})*/

		return resMap, true
	}

	if _, ok := resMap["errcode"]; ok {
		logging.Fatal(resMap["errmsg"])
	}

	return nil, false
}

/**
	获取access_token
 */
func GetAccessToken(c *gin.Context) string {
	// 读取缓存并校验有效性
	session := sessions.Default(c)
	token := session.Get(REDIS_KEY_ACCESS_TOKEN)
	if token != nil && len(token.(string)) > 0 {
		return token.(string)
	}
	baseUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"

	res := request.Get(fmt.Sprintf(baseUrl, AppId, Secret))
	if res == "" {
		return ""
	}

	var resMap map[string]interface{}

	decoder := json.NewDecoder(bytes.NewBufferString(res))
	decoder.Decode(&resMap)

	if token, ok := resMap["access_token"]; ok {
		//设置缓存
		session.Set(REDIS_KEY_ACCESS_TOKEN, token)
		session.Options(sessions.Options{
			MaxAge: int(resMap["expires_in"].(float64) / 2),
		})
		return token.(string)
	}

	if _, ok := resMap["errcode"]; ok {
		logging.Fatal(resMap["errmsg"])
	}

	return ""
}
